package cn.symbio.pet.service.impl;

import cn.symbio.basic.config.BussinessException;
import cn.symbio.basic.domain.Point;
import cn.symbio.basic.util.*;
import cn.symbio.order.domain.OrderPetAcquisition;
import cn.symbio.order.mapper.OrderPetAcquisitionMapper;
import cn.symbio.org.domain.Employee;
import cn.symbio.org.domain.Shop;
import cn.symbio.org.mapper.EmployeeMapper;
import cn.symbio.org.mapper.ShopMapper;
import cn.symbio.pet.domain.SearchMasterMsg;
import cn.symbio.pet.domain.SearchMasterMsgAuditLog;
import cn.symbio.pet.dto.AcceptDto;
import cn.symbio.pet.mapper.SearchMasterMsgAuditLogMapper;
import cn.symbio.pet.mapper.SearchMasterMsgMapper;
import cn.symbio.pet.query.SearchMasterMsgQuery;
import cn.symbio.pet.service.ISearchMasterMsgService;
import cn.symbio.basic.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.temporal.Temporal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Stream;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author bitter
 * @since 2022-11-01
 */
@Service
public class SearchMasterMsgServiceImpl extends BaseServiceImpl<SearchMasterMsg> implements ISearchMasterMsgService {

    @Autowired
    private SearchMasterMsgMapper searchMasterMsgMapper;

    @Autowired
    private SearchMasterMsgAuditLogMapper searchMasterMsgAuditLogMapper;

    @Autowired
    private ShopMapper shopMapper;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private OrderPetAcquisitionMapper orderPetAcquisitionMapper;

    /**
     * 发布寻主
     * @param searchMasterMsg
     * @return
     */
    @Override
    @Transactional
    public AjaxResult publish(SearchMasterMsg searchMasterMsg) {
        // 保存到db，默认状态未审核
        searchMasterMsgMapper.add(searchMasterMsg);
        // 空校验
        if (StringUtils.isBlank(searchMasterMsg.getName())) {
            // 失败保存日志
            addLog(searchMasterMsg,"参数不能为空，审核失败，请到个人中心修改编辑！！");
            throw new BussinessException("参数不能为空，审核失败，请到个人中心修改编辑！！");
        }
        // ai校验
        StringBuilder sb = new StringBuilder();
        sb.append(searchMasterMsg.getName())
                .append(searchMasterMsg.getAddress())
                .append(searchMasterMsg.getCoatColor())
                .append(searchMasterMsg.getTitle());
        if (!BaiduAuditUtils.TextCensor(sb.toString())){
            // 失败保存日志
            addLog(searchMasterMsg,"内容存在色情低俗，审核失败，请到个人中心修改编辑！！");
            throw new BussinessException("内容存在色情低俗，审核失败，请到个人中心修改编辑！！");
        }
        // 成功去找50km店铺挂钩
        Point point = DistanceUtil.getPoint(searchMasterMsg.getAddress());
        List<Shop> all = shopMapper.findAll();
        Shop nearestShop = DistanceUtil.getNearestShop(point, all);
        // nearestShop不为空就是找到了
        if (nearestShop != null) {
            // 店铺挂钩
            searchMasterMsg.setShopId(nearestShop.getId());
        } // 没找到不作为
        // 修改状态
        searchMasterMsg.setState(1);
        searchMasterMsgMapper.update(searchMasterMsg);
        return AjaxResult.me();
    }


    /**
     *  不同状态寻主信息
     * @param query
     * @return
     */
    @Override
    public PageList<SearchMasterMsg> findSearchMasterMsgByState(SearchMasterMsgQuery query) {
        // 查询条数
        Integer totals = searchMasterMsgMapper.queryByCount(query);
        // 判断是否有数据
        if (totals == null || totals == 0) {
            return new PageList<>(0,new ArrayList<>());
        }
        // 查询数据
        List<SearchMasterMsg> searchMasterMsgs = searchMasterMsgMapper.queryByPage(query);
        // 封装返回
        return new PageList<>(totals,searchMasterMsgs);
    }

    /**
     * 拒单
     * @param id
     */
    @Override
    public void reject(Long id) {
        // 参数校验
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(id);
        if (searchMasterMsg == null ) {
            throw new BussinessException("寻主消息不存在！！！");
        }
        // 将shopId置空
        searchMasterMsg.setShopId(null);
        searchMasterMsgMapper.update(searchMasterMsg);
        // 添加日志
        addLog(searchMasterMsg,"拒绝了该订单！！！");
    }

    /**
     * 接单
     * @param acceptDto
     */
    @Override
    @Transactional
    public void accept(AcceptDto acceptDto) {
        // 数据校验
        SearchMasterMsg searchMasterMsg = searchMasterMsgMapper.findById(acceptDto.getMsgId());
        if (searchMasterMsg == null ){
            throw new BussinessException("寻主消息不存在！！！");
        }
        // 解决线程安全问题
        synchronized (searchMasterMsg.getId()){
            // 判断当前接单人是否存在
            Employee employee = employeeMapper.findById(acceptDto.getHandler());
            if (employee == null){
                throw new BussinessException("当前员工不存在！！！");
            }
            // 判断当前寻主状态为1,并且shopId是他本身店铺id
            if (searchMasterMsg.getState() == 1 && searchMasterMsg.getShopId().equals(employee.getShopId())   ){
                // 修改寻主状态为2
                searchMasterMsg.setState(2);
                searchMasterMsgMapper.update(searchMasterMsg);
                // 保存订单表
                OrderPetAcquisition orderPetAcquisition = initOrder(acceptDto, searchMasterMsg, employee);
                orderPetAcquisitionMapper.add(orderPetAcquisition);
            }
        }
    }

    /**
     * 出事化订单
     * @param acceptDto
     * @param searchMasterMsg
     * @param employee
     * @return
     */
    private OrderPetAcquisition initOrder(AcceptDto acceptDto, SearchMasterMsg searchMasterMsg, Employee employee) {
        return OrderPetAcquisition
                .builder()
                .orderSn(CodeGenerateUtils.generateOrderSn(10))
                .digest(acceptDto.getNote())
                .lastConfirmTime(new Date(System.currentTimeMillis() + 3 * 24 * 60 * 60 * 1000))
                .price(new BigDecimal(searchMasterMsg.getPrice()))
                .userId(searchMasterMsg.getUserId())
                .shopId(searchMasterMsg.getShopId())
                .state(0)
                .petId(searchMasterMsg.getId())
                .address(searchMasterMsg.getAddress())
                .empId(employee.getId())
                .build();
    }


    /**
     *  失败保存日志
     * @param searchMasterMsg
     */
    private void addLog(SearchMasterMsg searchMasterMsg,String note) {
        SearchMasterMsgAuditLog smma = new SearchMasterMsgAuditLog();
        smma.setMsgId(searchMasterMsg.getId());
        smma.setNote(note);
        searchMasterMsgAuditLogMapper.add(smma);
    }
}
